<script lang='ts' setup>
import { PropType, reactive, watch } from 'vue'
import { new_v2ray_empty_vmess_client, new_v2ray_inbound_empty_vmess, V2rayInboundVMess } from '@/apis/application/v2ray/structs.ts'
import { v4 } from 'uuid'
import { v2ray_set_inbound_vmess } from '@/apis/application/v2ray/v2ray_set_inbound_vmess.ts'
import ApplicationV2rayBoundStreamSettings from '@/components/applications/v2ray/ApplicationV2rayBoundStreamSettings.vue'

const emits = defineEmits(['update:show', 'success'])
const props = defineProps({
  show: { required: true, type: Boolean },
  protocol: { required: true, type: Object as PropType<V2rayInboundVMess> }
})

watch(props, (_, n) => {
  if (n.show) {
    state.vmess = JSON.parse(JSON.stringify(n.protocol))
  }
})

const state = reactive<{ vmess: V2rayInboundVMess, saving: boolean }>({ vmess: new_v2ray_inbound_empty_vmess(), saving: false })

async function close(): Promise<void> {
  emits('update:show', false)
}

async function save(): Promise<void> {
  if ('' === state.vmess.inbound_listen.trim()) {
    window.$message.error('本地监听地址不能为空')

    return
  }

  if (0 === state.vmess.clients.length) {
    window.$message.error('客户端配置不能为空，最少添加一个客户端')

    return
  }

  for (let i = 0; i < state.vmess.clients.length; i++) {
    if ('' === state.vmess.clients[i].id.trim()) {
      window.$message.error('客户端ID不能为空')

      return
    }
  }

  if (state.vmess.stream_settings.enable) {
    if ('domainsocket' === state.vmess.stream_settings.network && '' === state.vmess.stream_settings.domain_socket_settings.path) {
      window.$message.error('DomainSocket的路径不能为空')

      return
    }

    if ('quic' === state.vmess.stream_settings.network && 'none' !== state.vmess.stream_settings.quic_settings.security && '' === state.vmess.stream_settings.quic_settings.key) {
      window.$message.error('Quic启用加密传输时，加密秘钥不能为空')

      return
    }
  }

  state.saving = true
  const response = await v2ray_set_inbound_vmess(state.vmess)
  state.saving = false

  if (0 !== response.code) {
    window.$message.error(response.message)

    return
  }

  window.$message.success('添加成功，重启应用后生效')

  emits('success')
  await close()
}
</script>

<template>
  <n-modal :closable='false' :close-on-esc='false' :mask-closable='false' :show='props.show' class='v2ray-bound-modal' transform-origin='center'>
    <n-card>
      <n-space vertical>
        <n-divider>入站基础配置</n-divider>
        <div>
          <n-space :wrap-item='false' align='center'>
            <div class='width-05'>
              <n-input-group>
                <n-input-group-label size='small'>配置ID</n-input-group-label>
                <n-input v-model:value='state.vmess.id' placeholder='配置ID，可以为空，为空时创建新的配置' size='small' />
              </n-input-group>
            </div>
            <div class='flex-max'>
              <n-input-group>
                <n-input-group-label size='small'>配置标签</n-input-group-label>
                <n-input v-model:value='state.vmess.tag' placeholder='配置标签，可以为空，不为空时必须唯一' size='small' />
              </n-input-group>
            </div>
          </n-space>
        </div>
        <div>
          <n-space :wrap-item='false' align='center'>
            <div class='width-05'>
              <n-input-group>
                <n-input-group-label size='small'>监听地址</n-input-group-label>
                <n-input v-model:value='state.vmess.inbound_listen' placeholder='输入监听的服务器IP地址' size='small' />
              </n-input-group>
            </div>
            <div class='flex-max'>
              <n-input-group>
                <n-input-group-label size='small'>监听端口</n-input-group-label>
                <n-input-number v-model:value='state.vmess.inbound_port' class='width-max' max='9999' min='1000' placeholder='输入监听的服务器端口号，最小1000，最大9999' size='small' />
              </n-input-group>
            </div>
          </n-space>
        </div>
        <n-divider>VMess协议配置</n-divider>
        <div>
          <n-space :wrap-item='false' align='center'>
            <div>禁用不安全的加密方式</div>
            <n-switch v-model:value='state.vmess.disable_insecure_encryption' size='small' />
          </n-space>
        </div>
        <template v-for='(client, index) in state.vmess.clients' :key='index'>
          <div>
            <n-space :wrap-item='false' align='center'>
              <div class='flex-2'>
                <n-input-group>
                  <n-input-group-label size='small'>用户ID</n-input-group-label>
                  <n-input v-model:value='client.id' placeholder='唯一ID，最少16位，最多64位' size='small' />
                  <n-button size='small' type='primary' @click='client.id = v4()'>随机生成</n-button>
                </n-input-group>
              </div>
              <div class='flex-2'>
                <n-input-group>
                  <n-input-group-label size='small'>邮件地址</n-input-group-label>
                  <n-input v-model:value='client.email' placeholder='邮件地址，可以为空，仅用于统计' size='small' />
                </n-input-group>
              </div>
              <div>
                <n-input-group>
                  <n-input-group-label size='small'>用户级别</n-input-group-label>
                  <n-input-number v-model:value='client.level' placeholder='用户级别，默认为0，仅用于本地策略' size='small' />
                </n-input-group>
              </div>
              <div>
                <n-button size='small' type='error' @click='state.vmess.clients.splice(index, 1)'>移除</n-button>
              </div>
            </n-space>
          </div>
        </template>
        <div>
          <n-button class='width-max' size='small' type='primary' @click='state.vmess.clients.push(new_v2ray_empty_vmess_client())'>添加客户端</n-button>
        </div>
        <ApplicationV2rayBoundStreamSettings :stream='state.vmess.stream_settings' />
        <div>
          <n-space align='center' justify='center'>
            <n-button size='small' type='error' @click='close'>取消</n-button>
            <n-button size='small' type='primary' @click='save'>保存</n-button>
          </n-space>
        </div>
      </n-space>
    </n-card>
  </n-modal>
</template>

<style scoped>

</style>
